﻿using DIM_Log;
using DIM_Tool;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net;
using System.Text;

namespace DIM_Agreement
{
    public class HTTP : IDisposable
    {
        private bool If_ { get; set; }
        private HttpListener Httpobj { set; get; }
        /// <summary>
        /// 启动监听
        /// </summary>
        public void Main_checker(string port)
        {
            //提供一个简单的、可通过编程方式控制的 HTTP 协议侦听器。此类不能被继承。
            Httpobj = new HttpListener();
            //定义url及端口号，通常设置为配置文件
            Httpobj.Prefixes.Add(string.Format("http://+:{0}/", port));
            If_ = false;
            //启动监听器
            Httpobj.Start();
            //异步监听客户端请求，当客户端的网络请求到来时会自动执行Result委托
            //该委托没有返回值，有一个IAsyncResult接口的参数，可通过该参数获取context对象
            Httpobj.BeginGetContext(Result, null);
            Program_log.Log_Info("服务端初始化完毕，正在等待客户端请求");
        }
        /// <summary>
        /// 异步监听进程
        /// </summary>
        private void Result(IAsyncResult ar)
        {
            if (If_) return;
            //当接收到请求后程序流会走到这里
            //继续异步监听
            Httpobj.BeginGetContext(Result, null);
            var guid = Guid.NewGuid().ToString();
            //获得context对象
            var context = Httpobj.EndGetContext(ar);
            var request = context.Request;
            var response = context.Response;
            context.Response.ContentType = "text/plain;charset=UTF-8";//告诉客户端返回的ContentType类型为纯文本格式，编码为UTF-8
            context.Response.AddHeader("Content-type", "text/plain");//添加响应头信息
            context.Response.ContentEncoding = Encoding.UTF8;
            string returnObj = null;//定义返回客户端的信息
            if (request.HttpMethod == "POST" && request.InputStream != null)
            {
                //处理客户端发送的请求并返回处理信息
                returnObj = HandleRequest(request, response);
            }
            else
            {
                returnObj = $"不是post请求或者传过来的数据为空";
            }
            var returnByteArr = Encoding.UTF8.GetBytes(returnObj);//设置客户端返回信息的编码
            try
            {
                using (var stream = response.OutputStream)
                {
                    //把处理信息返回到客户端
                    stream.Write(returnByteArr, 0, returnByteArr.Length);
                }
            }
            catch (Exception ex)
            {
                Program_log.Log_Error($"网络蹦了：{ex}");
            }
        }
        /// <summary>
        /// 数据转换
        /// </summary>
        private string HandleRequest(HttpListenerRequest request, HttpListenerResponse response)
        {
            try
            {
                string data;
                var byteList = new List<byte>();
                var byteArr = new byte[2048];
                int readLen = 0;
                int len = 0;
                //接收客户端传过来的数据并转成字符串类型
                do
                {
                    readLen = request.InputStream.Read(byteArr, 0, byteArr.Length);

                    len += readLen;

                    byteList.AddRange(byteArr);
                }
                while (readLen != 0);

                data = Encoding.UTF8.GetString(byteList.ToArray(), 0, len);

                //获取得到数据data可以进行其他操作
                response.StatusDescription = "200";//获取或设置返回给客户端的 HTTP 状态代码的文本说明。

                response.StatusCode = 200;// 获取或设置返回给客户端的 HTTP 状态代码。

                Tuple<int, string> tuple = HTTP_tool.Function_tool($"{data.Trim()}");

                Program_log.Log_Info($"接收数据完成:{data.Trim()}");

                var str_info = new Body("响应成功", tuple.Item2, tuple.Item1);

                return JsonConvert.SerializeObject(str_info);
            }
            catch (Exception ex)
            {
                response.StatusDescription = "400";

                response.StatusCode = 400;

                string mess = ex.Message;

                Program_log.Log_Error($"在接收数据时发生错误:{ex}");

                var str_error = new Body("响应失败", mess, 404);

                return JsonConvert.SerializeObject(str_error);
            }
        }
        public void Dispose()
        {
            Httpobj.Stop();
            If_ = true;
            GC.SuppressFinalize(this);  //系统资源垃圾桶资源回收
        }
    }
}
